package com.lognsoft.shell;

import java.lang.Thread;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;

public class AsyncStreamReader extends Thread
{

	private class StringOut extends OutputStream
	{
		private StringBuffer _buffer = new StringBuffer();
		
	    public void write(int b) throws IOException
	    {
	    	if ( b == '\r' )
	    	{
	    		return;
	    	}
	    	
	    	if (b == 0 || b == '\n')
	    	{
	    		b = ' ';
	    	}
	    	
	    	_buffer.append( (char) b );	    	
	    } 
	    
	    public String getAsString()
	    {
	    	return _buffer.toString();
	    }
	};	
	
	InputStream _in = null;
	OutputStream _out = null;
	Object _sync = new Object();
	boolean _is_closed = false;
	boolean _close_out = true;
	
public	AsyncStreamReader(InputStream s_in)
{
	_in = s_in;
	setDaemon(true);
}
	
public void setStringOut()
{
	_out = new StringOut();
}
	
public void setStringLineOut(ArrayList<String> lines)
{
	_out = new StringLineOutputStream(lines);
}
	
public void setStreamOut(OutputStream ot, boolean s_close_out)
{
	_out = ot;
	_close_out = s_close_out;
}
	
public String getAsString()
{
	if ( _out instanceof StringOut)
	{
		return ((StringOut)_out).getAsString();
	}
	else
	{
		return "";
	}
}	
	
public	void waitResult (int time_out)
{
	synchronized (_sync)
	{
		if (false == _is_closed)
		{
			try
			{
				if (time_out < 0 )
				{
					_sync.wait();
				}
				else
				{
					_sync.wait(time_out);
				}
			}
			catch (InterruptedException e)
			{
				Thread.currentThread().interrupt();
			}
		}
	}
};
	
@Override
public void run()
{
	try
	{
		synchronized (_sync)
		{				
			byte[] buffer = new byte[8192];
			int len;
				
			while ( (len = _in.read(buffer)) > 0 )
			{
				if ( _out != null)
				{
					_out.write(buffer,0,len);
				}
			}
			
			if (_out != null)
			{
				_out.flush();
				
				if (_close_out)
				{
					_out.close();
				}
			}
				
			_sync.notifyAll();
			_is_closed = true;
		}
	}
	catch (Exception e)
	{
		synchronized (_sync)
		{
			_sync.notifyAll();
			_is_closed = true;
		}
	}
}

}
